#include "Midi.hpp"

const static int iLoop      = 1;
const static int iNoLoop    = 0;

typedef enum eMidiState
{
    eMidiInvalid = 0,
    eMidiLoaded,
    eMidiPlaying,
    eMidiStopped,
    eMidiPaused
};

Midi::Midi(string path) : m_sFilename(path)
{
    m_pMidi = load_midi(path.c_str());

    if (m_pMidi)
    {
        m_eState = eMidiLoaded;
        m_iLength = get_midi_length(m_pMidi);
    }
    else
    {
        m_eState = eMidiInvalid;
        m_iLength = 0;    
    }
}

Midi::~Midi()
{
    if (m_pMidi)
        destroy_midi(m_pMidi);
}

bool Midi::IsReady() const
{
    return m_eState!=eMidiInvalid;
}

bool Midi::IsPlaying() const
{
    return m_eState==eMidiPlaying;
}

bool Midi::IsPaused() const
{
    return m_eState==eMidiPaused;
}

bool Midi::Play(bool abLoop /* = false*/)
{
    if (m_eState==eMidiInvalid)
        return false;

    if (m_eState==eMidiLoaded || m_eState==eMidiStopped)
    {
        int loop = abLoop ? iLoop : iNoLoop;
        if (play_midi(m_pMidi, loop)==0)
        {
            m_eState = eMidiPlaying;
            return true;
        }
        return false;
    }
    return false;
}

void Midi::Stop()
{
    if (m_eState!=eMidiInvalid)
        m_eState = eMidiStopped;

    stop_midi();    
}

bool Midi::Loop(int start, int end)
{
    if (m_eState==eMidiInvalid)
        return false;

    if (start < 0)
        return false;

    if (m_eState!=eMidiPlaying && m_eState!=eMidiPaused)
    {
        if (play_looped_midi(m_pMidi, start, end)==0)
        {
            m_eState = eMidiPlaying;
            return true;
        }
    }

    return false;
}

bool Midi::Pause() 
{
    if (m_eState==eMidiPlaying)
    {
        midi_pause();
        m_eState = eMidiPaused;
        return true;
    }

    return false;
}

bool Midi::Resume()
{
    if (m_eState==eMidiPaused)
    {
        midi_resume();
        m_eState = eMidiPlaying;
        return true;
    }

    return false;
}

bool Midi::Seek(int aiTarget)
{
    if (m_eState==eMidiInvalid)
        return false;

    if (aiTarget < 0)
        return false;

    int y = midi_seek(aiTarget);
    if (y==0)
        return true;
    else
        return false;
}